k-图着色
Get the knowledge flowing and circulating! :)
目录
标题:图的着色问题概念相关问题相关术语通俗说法代码代码 -
无向图
图着色问题(Graph Coloring Problem,GCP),又称着色问题,是最著名的NP-完全问题之一。
给定一个无向图
道路着色问题(Road Coloring Problem)是图论中最著名的猜想之一。
参考:维基百科
图的
图的
图色数(英语:chromatic number),也被称为顶点色数(vertex chromatic number):指将一张图上的每个顶点染色,使得相邻的两个点颜色不同,最小需要的颜色数。最小染色数用
边色数(edge chromatic number):指将一张图上的每条边染色,使有公共顶点的边颜色不同,最少需要的颜色数叫边色数,用
问题1
-着色判定问题 给定一个图
,给定一个 种颜色,有没有一个方案能够让图 中的任意相邻顶点的颜色不一样?
有没有?(True or False)
原图 方案1 问题2
-着色判定问题拓展 给定一个图
,给定一个 种颜色,有多少方案能够让图 中的任意相邻顶点的颜色不一样?
有多少?(How many)
从这个拓展问题可知,
-着色的答案不唯一。
原图 方案1 方案2
问题3 m-着色优化问题
给定一个图
,若该图至少需要 种颜色才能够让图 中的任意相邻顶点的颜色不一样,问这个 是多少?
是多少?
问题1
xxxxxxxxxx
751
2
3using namespace std;
4
5const int maxn = 105;
6
7int G[maxn][maxn];
8int color[maxn];
9
10// ans 表示是否存在方案[0:不存在;1:存在]。
11bool ans; // ans如果是1,则表示对于图G,可以用m种颜色着色,使G中每条边的2个顶点着不同颜色。
12
13// n:顶点数
14// m:颜色数
15// k:边数
16int n, m, k;
17
18void init()
19{
20 ans = 0; // 初始时,表示不存在这样的方案。
21 memset(G, 0, sizeof G);
22 memset(color, 0 , sizeof color);
23}
24
25void dfs(int cur)
26{
27 if(cur > n)
28 {
29 ans = 1;
30 return;
31 }
32 for(int i = 1; i <= m; i++) // 对cur结点尝试使用每一种颜色进行涂色
33 {
34 bool flag = 1;
35 // cur之前的结点必被涂色
36 for(int j = 1; j < cur; j++)
37 {
38 if(G[j][cur] == 1 && color[j] == i)
39 {
40 flag = 0; // 只要有一个冲突都不行
41 break;
42 }
43 }
44 // 如果可以涂上i颜色,则考虑下一个结点的情况
45 if(flag)
46 {
47 color[cur] = i; // 涂上颜色
48 dfs(cur + 1);
49 }
50 else // 如果到这一步第cur个结点无法着色,则返回探寻其他方案
51 {
52 color[cur] = 0; // 擦除颜色(回溯);
53 }
54 }
55
56}
57
58
59int main()
60{
61 // 可以一个窗口输入多组数据
62 while(cin>>n>>k>>m)
63 {
64 init();
65 for(int i = 1; i <= k; i++)
66 {
67 int s, e;
68 cin>>s>>e;
69 G[s][e] = G[e][s] = 1; // 无向图(对称)
70 }
71 dfs(1);
72 cout<<ans<<endl; // 输出 0 | 1
73 }
74 return 0;
75}
问题2
xxxxxxxxxx
1071
2
3using namespace std;
4
5const int maxn = 105;
6
7int G[maxn][maxn];
8int color[maxn];
9
10
11// 图着色判断问题(拓展)
12// ans 表示存在多少种方案
13int ans;
14
15// n:顶点数
16// m:颜色数
17// k:边数
18int n, m, k;
19
20void init()
21{
22 ans = 0; // 初始时默认为没有方案。
23 memset(G, 0, sizeof G);
24 memset(color, 0 , sizeof color);
25}
26
27void dfs(int cur)
28{
29 if(cur > n)
30 {
31 ans = ans + 1; // 找到1种,就加1
32 return;
33 }
34 for(int i = 1; i <= m; i++) // 对cur结点尝试使用每一种颜色进行涂色
35 {
36 bool flag = 1;
37 // cur之前的结点必被涂色
38 for(int j = 1; j < cur; j++)
39 {
40 if(G[j][cur] == 1 && color[j] == i)
41 {
42 flag = 0; // 只要有一个冲突都不行
43 break;
44 }
45 }
46 // 如果可以涂上i颜色,则考虑下一个结点的情况
47 if(flag)
48 {
49 color[cur] = i; // 涂上颜色
50 dfs(cur + 1);
51 color[cur] = 0; // 擦除颜色(回溯)
52 }
53 }
54
55}
56
57void dfs2(int cur)
58{
59 if(cur > n)
60 {
61 ans = ans + 1; // 找到1种,就加1
62 return;
63 }
64 for(int i = 1; i <= m; i++) // 对cur结点尝试使用每一种颜色进行涂色
65 {
66 color[cur] = i; // 涂上颜色(先涂了再说)
67
68 int flag = 1;
69 // cur和其他节点的涂色情况检查
70 for(int j = 1; j <= n; j++)
71 {
72 if(G[j][cur] == 1 && color[j] == i)
73 {
74 flag = 0; // 只要有一个冲突都不行
75 break;
76 }
77 }
78 // 如果可以涂上i颜色,则考虑下一个结点的情况
79
80 // 如果检查通过,则flag还是1(没有进入上面for循环里的if语句)
81 // 如果检查没通过,则flag肯定是0了(下面这句if就不执行了)
82 if(flag)
83 {
84 dfs2(cur + 1);
85 }
86
87 color[cur] = 0; // 擦除颜色(回溯)
88 }
89}
90
91int main()
92{
93 // 可以一个窗口输入多组数据
94 while(cin>>n>>k>>m)
95 {
96 init();
97 for(int i = 1; i <= k; i++)
98 {
99 int s, e;
100 cin>>s>>e;
101 G[s][e] = G[e][s] = 1; // 无向图(对称)
102 }
103 dfs(1); //dfs2(1),测试第2种代码(思路更清晰)
104 cout<<ans<<endl; // 输出总方案数
105 }
106 return 0;
107}
5个顶点:编号从1~5
7条边
3种颜色:红、绿、蓝
注意:顶点编号从1开始,不是从0开始。
输出:6
xxxxxxxxxx
815 7 3
21 2
32 3
43 4
54 5
65 1
71 3
81 4
13个顶点:编号从1~13
41条边
3种颜色:红、绿、蓝
注意:顶点编号从1开始,不是从0开始。
输出:336
xxxxxxxxxx
42113 41 3
21 3
31 5
41 6
51 10
62 5
72 6
82 7
93 1
103 4
113 5
123 13
134 7
144 8
155 1
165 2
175 3
185 6
195 9
206 1
216 2
226 5
236 12
246 13
257 2
267 4
277 11
288 4
298 11
309 5
319 10
3210 1
3310 9
3410 11
3510 13
3611 7
3711 8
3811 10
3912 6
4013 3
4113 6
4213 10
xxxxxxxxxx
815 7 3
21 3
31 4
42 3
52 5
63 4
73 5
84 5
针对
void dfs(int cur)
和 测试样例2的过程示意图(输出1种着色方案)
条件:元素=[1,2,3,4,5,6,7,8,9],互斥=[(1,4),(2,5),(1,5),(5,6),(7,8),(3,9),(2,8),(4,5)]
要求:把元素组成
个组, 保证互斥元素不在同一个组里, 并且 最小。 思路:这个问题实际上就是图的
-可着色优化问题。
https://blog.csdn.net/qq_17550379/article/details/102563756
https://blog.csdn.net/Wu_L7/article/details/125062506
https://oi-wiki.org/graph/color/
https://baike.baidu.com/item/%E5%9B%BE%E7%9D%80%E8%89%B2%E9%97%AE%E9%A2%98/8928655